package com.ruoyi.system.service.impl;

import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.uuid.SnowflakeUtils;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.domain.vo.ACreateResultVo;
import com.ruoyi.system.domain.vo.ARouteVo;
import com.ruoyi.system.domain.vo.ARuKuVo;
import com.ruoyi.system.mapper.*;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.system.service.IAResultService;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;

/**
 * 追溯结果Service业务层处理
 * 
 * @author ruoyi
 * @date 2025-03-16
 */
@Service
public class AResultServiceImpl implements IAResultService 
{
    @Autowired
    private AResultMapper aResultMapper;

    @Autowired
    private AProcessRouteMapper processRouteMapper;

    @Autowired
    private AWareJlMapper aWareJlMapper;

    @Autowired
    private AWareWbMapper aWareWbMapper;

    @Autowired
    private AWareFlMapper aWareFlMapper;

    @Autowired
    private AStepMapper aStepMapper;

    @Autowired
    private AEqpMapper aEqpMapper;

    @Autowired
    private AWorkorderMapper aWorkorderMapper;

    private Random rand = new Random();

    /**
     * 查询追溯结果
     * 
     * @param id 追溯结果主键
     * @return 追溯结果
     */
    @Override
    public AResult selectAResultById(Long id)
    {
        return aResultMapper.selectAResultById(id);
    }

    /**
     * 查询追溯结果列表
     * 
     * @param aResult 追溯结果
     * @return 追溯结果
     */
    @Override
    public List<AResult> selectAResultList(AResult aResult)
    {
        return aResultMapper.selectAResultList(aResult);
    }

    /**
     * 新增追溯结果
     * 
     * @param aResult 追溯结果
     * @return 结果
     */
    @Override
    public int insertAResult(AResult aResult)
    {
        return aResultMapper.insertAResult(aResult);
    }

    /**
     * 修改追溯结果
     * 
     * @param aResult 追溯结果
     * @return 结果
     */
    @Override
    public int updateAResult(AResult aResult)
    {
        return aResultMapper.updateAResult(aResult);
    }

    /**
     * 批量删除追溯结果
     * 
     * @param ids 需要删除的追溯结果主键
     * @return 结果
     */
    @Override
    public int deleteAResultByIds(Long[] ids)
    {
        return aResultMapper.deleteAResultByIds(ids);
    }

    /**
     * 删除追溯结果信息
     * 
     * @param id 追溯结果主键
     * @return 结果
     */
    @Override
    public int deleteAResultById(Long id)
    {
        return aResultMapper.deleteAResultById(id);
    }

    // 工艺路线列表
    @Override
    public List<ARouteVo> routeList() {
        ARouteVo routeVo = new ARouteVo();
        routeVo.setGroupId(String.valueOf(SecurityUtils.getLoginUser().getDeptId()));
        return aResultMapper.routeList(routeVo);
    }

    // 生成追溯数据
    @Override
    @Transactional
    public AjaxResult createResult(JSONObject jo) throws Exception {
        JSONObject main = jo.getJSONObject("main");
        JSONArray array = jo.getJSONArray("rows");
        List<ACreateResultVo> resultVoList = array.toJavaList(ACreateResultVo.class);
        // 单个生成中，输入多个小包号；无论是单个还是批量生成，小包号前端卡控都不允许为空，此处不用考虑空指针问题
        if (CollectionUtils.isNotEmpty(resultVoList) && resultVoList.size() == 1 && resultVoList.get(0).getPackName().contains("\n")) {
            String packNameArr[] = resultVoList.get(0).getPackName().split("\n");
            if (packNameArr.length > 20) {
                throw new RuntimeException("一次最多只可以生成20个小包！");
            }
            ACreateResultVo rootVo = new ACreateResultVo();
            BeanUtils.copyProperties(resultVoList.get(0), rootVo);
            resultVoList = new ArrayList<>();
            for (String packName : packNameArr) {
                ACreateResultVo newVo = new ACreateResultVo();
                BeanUtils.copyProperties(rootVo, newVo);
                newVo.setPackName(packName);
                resultVoList.add(newVo);
            }
        }
        return createResult(main, resultVoList);
    }

    @Transactional
    public AjaxResult createResult(JSONObject main, List<ACreateResultVo> resultVoList) throws Exception {
        DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm");
        String routeId = main.getString("routeId");
        Integer packQty = main.getInteger("packQty");
        String beginPackTime = main.getString("beginPackTime");
        String endPackTime = main.getString("endPackTime");
        String groupId = String.valueOf(SecurityUtils.getLoginUser().getDeptId());
        ARouteVo routeVo = new ARouteVo();
        routeVo.setGroupId(groupId);
        routeVo.setRouteId(routeId);
        List<ARouteVo> routeList = aResultMapper.routeList(routeVo);
        if (CollectionUtils.isEmpty(routeList)) {
            throw new RuntimeException("工艺路线：" + routeId + "，不存在!");
        }
        routeVo = routeList.get(0);
        AProcessRoute queryProcessRoute = new AProcessRoute();
        queryProcessRoute.setRouteId(routeId);
        List<AProcessRoute> processRouteList = processRouteMapper.selectAProcessRouteList(queryProcessRoute);
        processRouteList.sort((p1, p2) -> Long.compare(p2.getStepSort(), p1.getStepSort()));
        for (ACreateResultVo item : resultVoList) {
            item.setPackQty(null != item.getPackQty() ? item.getPackQty() : packQty);
            if (StringUtils.isNotEmpty(item.getPackTime1())) {
                item.setPackTime(dateFormat.parse(item.getPackTime1()));
            } else {
                long beginTime = dateFormat.parse(beginPackTime).getTime();
                long endTime = dateFormat.parse(endPackTime).getTime();
                long randomTime = beginTime + (long) (rand.nextDouble() * ((endTime - beginTime) + 1));
                item.setPackTime(new Date(randomTime));
            }
            int restQty = item.getPackQty();
            // 每包拆成几份
            while(true) {
                int randomQty = rand.nextInt(item.getPackQty()) + 1;
                restQty -= randomQty;
                randomQty = restQty <= 0 ? restQty + randomQty : randomQty;
                restQty = restQty <= 0 ? 0 : restQty;
                // 获取工单信息
                AWorkorder queryWorkOrder = new AWorkorder();
                queryWorkOrder.setGroupId(groupId);
                queryWorkOrder.setProcessRoute(routeId);
                queryWorkOrder.setProductionOrder(item.getProductionOrder());
                List<AWorkorder> workOrderList = aWorkorderMapper.selectAWorkorderList(queryWorkOrder);
                // 入包工序固定
                AResult newResult = new AResult();
                newResult.setId(SnowflakeUtils.nextId());
                newResult.setGroupId(groupId);
                newResult.setRouteId(routeId);
                newResult.setRouteName(routeVo.getRouteName());
                newResult.setStep("PACK");
                newResult.setStepName("入包");
                newResult.setTrackInTime(item.getPackTime());
                newResult.setPackName(item.getPackName());
                newResult.setQty((long) randomQty);
                newResult.setProductionOrder(item.getProductionOrder());
                newResult.setInBatchNo(item.getInBatchNo());
                newResult.setPalletNo(item.getPalletNo());
                newResult.setBoxNo(item.getBoxNo());
                newResult.setProductCode(CollectionUtils.isNotEmpty(workOrderList) ? workOrderList.get(0).getProductCode() : null);
                newResult.setProductDesc(CollectionUtils.isNotEmpty(workOrderList) ? workOrderList.get(0).getProductDesc() : null);
                newResult.setProductionPlant(CollectionUtils.isNotEmpty(workOrderList) ? workOrderList.get(0).getProductionPlant() : null);
                newResult.setProductionType(CollectionUtils.isNotEmpty(workOrderList) ? workOrderList.get(0).getType() : null);
                newResult.setEfficiency(item.getEfficiency());
                newResult.setUnit("PCS");
                newResult.setColor(getInfoFromBoxNo(item.getBoxNo(), "color")); // item.getColor()
                newResult.setPressure(item.getPressure());
                newResult.setPower(item.getPower());
                newResult.setGrade(getInfoFromBoxNo(item.getBoxNo(), "grade"));   // item.getGrade()
                aResultMapper.insertAResult(newResult);
                // 初始化
                Date eventTime = item.getPackTime();
                Long preId = newResult.getId();
                // 循环寻找下一工序
                for (AProcessRoute itemStep : processRouteList) {
                    AResult itemNewResult = new AResult();
                    // 判断是否启用一些批次管理，根据情况匹配设备号、批次和扣减对应配置数量
                    // 未启用批次管理的，则随机匹配同组同工序的设备号
                    // 工序qtime为0的，trackOutTime赋null
                    // 启用浆料批次
                    if ("Y".equals(itemStep.getJlflag())) {
                        int randomRest = randomQty;
                        for (int i = 0; i < itemStep.getJlbatchA().size(); i++) {
                            AWareJl wareJl = aWareJlMapper.selectAWareJlById(Long.parseLong(itemStep.getJlbatchA().get(i).toString()));
                            if (new BigDecimal(randomRest).multiply(wareJl.getUnit()).compareTo(wareJl.getRemaining()) <= 0) {
                                wareJl.setRemaining(wareJl.getRemaining().subtract(new BigDecimal(randomRest).multiply(wareJl.getUnit())));
                                randomRest = 0;
                            } else if (new BigDecimal(randomRest).multiply(wareJl.getUnit()).compareTo(wareJl.getRemaining()) > 0) {
                                randomRest -= Double.valueOf(wareJl.getRemaining().divide(wareJl.getUnit()).toString());
                                wareJl.setRemaining(new BigDecimal("0"));
                            }
                            aWareJlMapper.updateAWareJl(wareJl);    // 更新浆料表剩余数量
                            itemNewResult.setJlbatchA(StringUtils.isNotEmpty(itemNewResult.getJlbatchA()) ? itemNewResult.getJlbatchA() + "," + wareJl.getJlbatch() : wareJl.getJlbatch());
                            if (randomRest == 0) {
                                break;
                            }
                        }
                        if (randomRest != 0) {
                            throw new RuntimeException(itemStep.getStep() + "_" + itemStep.getStepName() + ";" + "一三道浆料批次不足");
                        }
                        randomRest = randomQty;
                        for (int i = 0; i < itemStep.getJlbatchB().size(); i++) {
                            AWareJl wareJl = aWareJlMapper.selectAWareJlById(Long.parseLong(itemStep.getJlbatchB().get(i).toString()));
                            if (new BigDecimal(randomRest).multiply(wareJl.getUnit()).compareTo(wareJl.getRemaining()) <= 0) {
                                wareJl.setRemaining(wareJl.getRemaining().subtract(new BigDecimal(randomRest).multiply(wareJl.getUnit())));
                                randomRest = 0;
                            } else if (new BigDecimal(randomRest).multiply(wareJl.getUnit()).compareTo(wareJl.getRemaining()) > 0) {
                                randomRest -= Double.valueOf(wareJl.getRemaining().divide(wareJl.getUnit()).toString());
                                wareJl.setRemaining(new BigDecimal("0"));
                            }
                            aWareJlMapper.updateAWareJl(wareJl);    // 更新浆料表剩余数量
                            itemNewResult.setJlbatchB(StringUtils.isNotEmpty(itemNewResult.getJlbatchB()) ? itemNewResult.getJlbatchB() + "," + wareJl.getJlbatch() : wareJl.getJlbatch());
                            if (randomRest == 0) {
                                break;
                            }
                        }
                        if (randomRest != 0) {
                            throw new RuntimeException(itemStep.getStep() + "_" + itemStep.getStepName() + ";" + "二四道浆料批次不足");
                        }
                    }
                    // 启用网板批次
                    if ("Y".equals(itemStep.getWbflag())) {
                        int randomRest = randomQty;
                        for (int i = 0; i < itemStep.getWbbatchA().size(); i++) {
                            AWareWb wareWb = aWareWbMapper.selectAWareWbById(Long.parseLong(itemStep.getWbbatchA().get(i).toString()));
                            if (randomRest <= wareWb.getRemaining()) {
                                wareWb.setRemaining(wareWb.getRemaining() - randomRest);
                                randomRest = 0;
                            } else if (randomRest > wareWb.getRemaining()) {
                                randomRest -= wareWb.getRemaining();
                                wareWb.setRemaining(0L);
                            }
                            aWareWbMapper.updateAWareWb(wareWb);    // 更新网板表剩余数量
                            itemNewResult.setWbbatchA(StringUtils.isNotEmpty(itemNewResult.getWbbatchA()) ? itemNewResult.getWbbatchA() + "," + wareWb.getWbbatch() : wareWb.getWbbatch());
                            if (randomRest == 0) {
                                break;
                            }
                        }
                        if (randomRest != 0) {
                            throw new RuntimeException(itemStep.getStep() + "_" + itemStep.getStepName() + ";" + "一道网板批次不足");
                        }
                        randomRest = randomQty;
                        for (int i = 0; i < itemStep.getWbbatchB().size(); i++) {
                            AWareWb wareWb = aWareWbMapper.selectAWareWbById(Long.parseLong(itemStep.getWbbatchB().get(i).toString()));
                            if (randomRest <= wareWb.getRemaining()) {
                                wareWb.setRemaining(wareWb.getRemaining() - randomRest);
                                randomRest = 0;
                            } else if (randomRest > wareWb.getRemaining()) {
                                randomRest -= wareWb.getRemaining();
                                wareWb.setRemaining(0L);
                            }
                            aWareWbMapper.updateAWareWb(wareWb);    // 更新网板表剩余数量
                            itemNewResult.setWbbatchB(StringUtils.isNotEmpty(itemNewResult.getWbbatchB()) ? itemNewResult.getWbbatchB() + "," + wareWb.getWbbatch() : wareWb.getWbbatch());
                            if (randomRest == 0) {
                                break;
                            }
                        }
                        if (randomRest != 0) {
                            throw new RuntimeException(itemStep.getStep() + "_" + itemStep.getStepName() + ";" + "二道网板批次不足");
                        }
                        randomRest = randomQty;
                        for (int i = 0; i < itemStep.getWbbatchC().size(); i++) {
                            AWareWb wareWb = aWareWbMapper.selectAWareWbById(Long.parseLong(itemStep.getWbbatchC().get(i).toString()));
                            if (randomRest <= wareWb.getRemaining()) {
                                wareWb.setRemaining(wareWb.getRemaining() - randomRest);
                                randomRest = 0;
                            } else if (randomRest > wareWb.getRemaining()) {
                                randomRest -= wareWb.getRemaining();
                                wareWb.setRemaining(0L);
                            }
                            aWareWbMapper.updateAWareWb(wareWb);    // 更新网板表剩余数量
                            itemNewResult.setWbbatchC(StringUtils.isNotEmpty(itemNewResult.getWbbatchC()) ? itemNewResult.getWbbatchC() + "," + wareWb.getWbbatch() : wareWb.getWbbatch());
                            if (randomRest == 0) {
                                break;
                            }
                        }
                        if (randomRest != 0) {
                            throw new RuntimeException(itemStep.getStep() + "_" + itemStep.getStepName() + ";" + "三道网板批次不足");
                        }
                        randomRest = randomQty;
                        for (int i = 0; i < itemStep.getWbbatchD().size(); i++) {
                            AWareWb wareWb = aWareWbMapper.selectAWareWbById(Long.parseLong(itemStep.getWbbatchD().get(i).toString()));
                            if (randomRest <= wareWb.getRemaining()) {
                                wareWb.setRemaining(wareWb.getRemaining() - randomRest);
                                randomRest = 0;
                            } else if (randomRest > wareWb.getRemaining()) {
                                randomRest -= wareWb.getRemaining();
                                wareWb.setRemaining(0L);
                            }
                            aWareWbMapper.updateAWareWb(wareWb);    // 更新网板表剩余数量
                            itemNewResult.setWbbatchD(StringUtils.isNotEmpty(itemNewResult.getWbbatchD()) ? itemNewResult.getWbbatchD() + "," + wareWb.getWbbatch() : wareWb.getWbbatch());
                            if (randomRest == 0) {
                                break;
                            }
                        }
                        if (randomRest != 0) {
                            throw new RuntimeException(itemStep.getStep() + "_" + itemStep.getStepName() + ";" + "四道网板批次不足");
                        }
                    }
                    // 启用发料批次
                    if ("Y".equals(itemStep.getFlflag())) {
                        int randomRest = randomQty;
                        for (int i = 0; i < itemStep.getFlbatch().size(); i++) {
                            AWareFl wareFl = aWareFlMapper.selectAWareFlById(Long.parseLong(itemStep.getFlbatch().get(i).toString()));

                            if(wareFl == null){
                                throw new RuntimeException("发料批次未获取到！请检查");
                            }
                            if (randomRest <= wareFl.getRemaining()) {
                                wareFl.setRemaining(wareFl.getRemaining() - randomRest);
                                randomRest = 0;
                            } else if (randomRest > wareFl.getRemaining()) {
                                randomRest -= wareFl.getRemaining();
                                wareFl.setRemaining(0L);
                            }
                            aWareFlMapper.updateAWareFl(wareFl);    // 更新发料表剩余数量
                            itemNewResult.setFlbatch(StringUtils.isNotEmpty(itemNewResult.getFlbatch()) ? itemNewResult.getFlbatch() + "," + wareFl.getFlbatch() : wareFl.getFlbatch());
                            if (randomRest == 0) {
                                break;
                            }
                        }
                        if (randomRest != 0) {
                            throw new RuntimeException(itemStep.getStep() + "_" + itemStep.getStepName() + ";" + "发料批次不足");
                        }
                    }
                    AStep queryStep = new AStep();
                    queryStep.setGroupId(groupId);
                    queryStep.setStep(itemStep.getStep());
                    List<AStep> stepList = aStepMapper.selectAStepList(queryStep);
                    if (CollectionUtils.isNotEmpty(stepList)) {
                        queryStep = stepList.get(0);
                    }
                    AEqp queryEqp = new AEqp();
                    queryEqp.setGroupId(groupId);
                    queryEqp.setStep(itemStep.getStep());
                    List<AEqp> eqpList = aEqpMapper.selectAEqpList(queryEqp);
                    if (CollectionUtils.isNotEmpty(eqpList)) {
                        queryEqp = eqpList.get(rand.nextInt(eqpList.size()));
                    }
                    Calendar calendar = Calendar.getInstance();
                    calendar.setTime(eventTime);
                    calendar.add(Calendar.MINUTE, -queryStep.getWaitTime().intValue());
                    if (queryStep.getQtime().intValue() != 0) {
                        itemNewResult.setTrackOutTime(calendar.getTime());
                        Calendar calendar1 = Calendar.getInstance();
                        calendar1.setTime(itemNewResult.getTrackOutTime());
                        calendar1.add(Calendar.MINUTE, -(queryStep.getQtime().intValue() + rand.nextInt(queryStep.getDfloat().intValue())));
                        itemNewResult.setTrackInTime(calendar1.getTime());
                    } else {
                        itemNewResult.setTrackInTime(calendar.getTime());
                    }
                    eventTime = itemNewResult.getTrackInTime();
                    itemNewResult.setId(SnowflakeUtils.nextId());
                    itemNewResult.setPreId(preId);
                    itemNewResult.setGroupId(groupId);
                    itemNewResult.setRouteId(routeId);
                    itemNewResult.setRouteName(routeVo.getRouteName());
                    itemNewResult.setStep(itemStep.getStep());
                    itemNewResult.setStepName(itemStep.getStepName());
                    itemNewResult.setEqpId(queryEqp.getEqpId());
                    aResultMapper.insertAResult(itemNewResult);
                    preId = itemNewResult.getId();
                    itemNewResult = null;
                }
                newResult = null;
                if (restQty == 0) {
                    break;
                }
            }
        }
        return AjaxResult.success();
    }

    // 查询第一层小包数据
    @Override
    public List<AResult> selectRetraceResultList(AResult aResult) {
        return aResultMapper.selectRetraceResultList(aResult);
    }

    // 动态显示追溯数据
    @Override
    public HashMap retraceResultList(AResult aResult) {
        HashMap resMap = new HashMap();
        // 结果数据集
        List<LinkedHashMap> resList = new ArrayList<>();
        // 第一层小包数据
//        aResult.setGroupId(String.valueOf(SecurityUtils.getLoginUser().getDeptId()));
        List<AResult> packList = selectRetraceResultList(aResult);
        // 追溯数据
        List<AResult> perNextList = new ArrayList<>();
        AResult queryParam = new AResult();
        for (int i = 0; i < packList.size(); i++) {
            perNextList.add(packList.get(i));
            LinkedHashMap everyMap = new LinkedHashMap();
//            everyMap.put("id", packList.get(i).getId());
//            everyMap.put("groupId", packList.get(i).getGroupId());
           // everyMap.put("包号", packList.get(i).getPackName());
            everyMap.put(MessageUtils.message("zs.SmallPackageNumber"), packList.get(i).getPackName());
            everyMap.put(MessageUtils.message("zs.Packingtime"), DateUtils.formatDate(packList.get(i).getTrackInTime(), "yyyy-MM-dd HH:mm"));
            everyMap.put(MessageUtils.message("zs.quantity"), packList.get(i).getQty() + "");
            while (true) {
                queryParam.setPreId(perNextList.get(0).getId());
                perNextList = selectAResultList(queryParam);
                if (CollectionUtils.isEmpty(perNextList)) {
                    break;
                }
                if (StringUtils.isNotEmpty(perNextList.get(0).getEqpId())) {
                    everyMap.put(perNextList.get(0).getStepName() + MessageUtils.message("zs.machine"), perNextList.get(0).getEqpId());
                }
                if (null != perNextList.get(0).getTrackInTime() && null == perNextList.get(0).getTrackOutTime()) {
                    everyMap.put(perNextList.get(0).getStepName() + MessageUtils.message("zs.time"), DateUtils.formatDate(perNextList.get(0).getTrackInTime(), "yyyy-MM-dd HH:mm"));
                }
                if (null != perNextList.get(0).getTrackInTime() && null != perNextList.get(0).getTrackOutTime()) {
                    everyMap.put(perNextList.get(0).getStepName() + MessageUtils.message("zs.outbound"), DateUtils.formatDate(perNextList.get(0).getTrackOutTime(), "yyyy-MM-dd HH:mm"));
                    everyMap.put(perNextList.get(0).getStepName() + MessageUtils.message("zs.pullin"), DateUtils.formatDate(perNextList.get(0).getTrackInTime(), "yyyy-MM-dd HH:mm"));
                }
                if (StringUtils.isNotEmpty(perNextList.get(0).getJlbatchA())) {
                    everyMap.put(MessageUtils.message("zs.pullin")+"1、3", perNextList.get(0).getJlbatchA());
                }
                if (StringUtils.isNotEmpty(perNextList.get(0).getJlbatchB())) {
                    everyMap.put(MessageUtils.message("zs.pullin")+"2、4", perNextList.get(0).getJlbatchB());
                }
                if (StringUtils.isNotEmpty(perNextList.get(0).getWbbatchA())) {
                    everyMap.put(MessageUtils.message("zs.meshplate")+"（1）", perNextList.get(0).getWbbatchA());
                }
                if (StringUtils.isNotEmpty(perNextList.get(0).getWbbatchB())) {
                    everyMap.put(MessageUtils.message("zs.meshplate")+"（2）", perNextList.get(0).getWbbatchB());
                }
                if (StringUtils.isNotEmpty(perNextList.get(0).getWbbatchC())) {
                    everyMap.put(MessageUtils.message("zs.meshplate")+"（3）", perNextList.get(0).getWbbatchC());
                }
                if (StringUtils.isNotEmpty(perNextList.get(0).getWbbatchD())) {
                    everyMap.put(MessageUtils.message("zs.meshplate")+"（4）", perNextList.get(0).getWbbatchD());
                }
                if (StringUtils.isNotEmpty(perNextList.get(0).getFlbatch())) {
                    everyMap.put(MessageUtils.message("zs.Batchofissuance"), perNextList.get(0).getFlbatch());
                }
            }
            everyMap.put(MessageUtils.message("zs.MaterialNumber"), packList.get(i).getProductCode());
            everyMap.put(MessageUtils.message("zs.productionplant"), packList.get(i).getProductionPlant());
            everyMap.put(MessageUtils.message("zs.ProductionType"), packList.get(i).getProductionType());
            everyMap.put(MessageUtils.message("zs.WorkOrderNumber"), packList.get(i).getProductionOrder());
            everyMap.put(MessageUtils.message("zs.BoxNo"), packList.get(i).getBoxNo());
            resList.add(everyMap);
        }
        resMap.put("packList", packList);
        resMap.put("resList", resList);
        return resMap;
    }

    /** 导出追溯 */
    @Override
    public void exportResult(HttpServletResponse response, AResult aResult) {
        HashMap resMap = retraceResultList(aResult);
        List<LinkedHashMap> list = (List) resMap.get("resList");
        Workbook workbook = new XSSFWorkbook();
        Sheet sheet = workbook.createSheet("追溯信息");
        if (CollectionUtils.isEmpty(list)) {
            throw new RuntimeException("导出数据为空，请正确筛选数据后导出！");
        }
        // 动态生成的表头数据
        List<String> headers = new ArrayList<>();
        LinkedHashMap<String, String> linkedHashMap = list.get(0);
        for (String key : linkedHashMap.keySet()) {
            headers.add(key);
        }
        // 创建表头行
        Row headerRow = sheet.createRow(0);
        // 动态生成表头
        for (int i = 0; i < headers.size(); i++) {
            Cell cell = headerRow.createCell(i);
            cell.setCellValue(headers.get(i));
        }
        // 添加数据行
        int rowNum = 1; // 从第二行开始添加数据
        for (LinkedHashMap<String, String> map : list) {
            Row row = sheet.createRow(rowNum++);
            int i = 0;
            for (String key : linkedHashMap.keySet()) {
                row.createCell(i).setCellValue(map.get(key));
                i++;
            }
        }
        // 将生成的Workbook对象文件发送到浏览器
        try {
            response.setContentType("application/vnd.ms-excel"); // 设置内容类型为Excel文件类型
            response.setHeader("Content-disposition", "attachment;filename=users.xls"); // 设置下载文件名和内容为附件形式
            workbook.write(response.getOutputStream()); // 将Workbook写入到响应输出流中，触发下载或显示Excel文件。
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 入库查询
    @Override
    public List<ARuKuVo> selectRuKuList(String inBatchNo) {
        return aResultMapper.selectRuKuList(inBatchNo, String.valueOf(SecurityUtils.getLoginUser().getDeptId()));
    }

    // 工单剩余数量查询
    @Override
    public AjaxResult getWorkOrderRestQty(String workOrder) {
        if (StringUtils.isEmpty(workOrder)) {
            return AjaxResult.success(0);
        }
        return AjaxResult.success(aResultMapper.getWorkOrderRestQty(workOrder));
    }


    // 工单剩余数量查询
    @Override
    public AjaxResult getBoxQty(String boxNo) {
        if (StringUtils.isEmpty(boxNo)) {
            return AjaxResult.success(0);
        }
        return AjaxResult.success(aResultMapper.getBoxQty(boxNo));
    }


    private String getInfoFromBoxNo(String boxNo, String type) {
        if (StringUtils.isEmpty(boxNo)) {
            throw new RuntimeException(MessageUtils.message("zs.boxempty"));
        }
        if (boxNo.length() != 29 && boxNo.length() != 34) {
            throw new RuntimeException(MessageUtils.message("zs.boxlength"));
        }
        if (boxNo.length() == 29) {
            if ("product_code".equals(type)) {
                return boxNo.substring(0, 11);
            }
            if ("color".equals(type)) {
                return boxNo.substring(11, 13);
            }
            if ("qty".equals(type)) {
                return boxNo.substring(13, 16);
            }
            if ("grade".equals(type)) {
                return boxNo.substring(16, 17);
            }
            if ("date_time".equals(type)) {
                return boxNo.substring(17, 23);
            }
            if ("work_shop".equals(type)) {
                return boxNo.substring(23, 24);
            }
        }
        if (boxNo.length() == 34) {
            if ("product_code".equals(type)) {
                return boxNo.substring(0, 11);
            }
            if ("color".equals(type)) {
                return boxNo.substring(11, 13);
            }
            if ("qty".equals(type)) {
                return boxNo.substring(13, 17);
            }
            if ("grade".equals(type)) {
                return boxNo.substring(17, 18);
            }
            if ("efficiency".equals(type)) {
                return boxNo.substring(18, 22);
            }
            if ("date_time".equals(type)) {
                return boxNo.substring(23, 29);
            }
            if ("work_shop".equals(type)) {
                return boxNo.substring(29, 30);
            }
        }
        return null;
    }

}
